home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dobj / code.c next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  15.7 KB  |  798 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  CODE.C
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. #define DISOBJ_C
  14.  
  15. #ifdef AMIGA
  16. #include "/das/ops.c"
  17. #else
  18. #include "../das/ops.c"
  19. #endif
  20.  
  21. OpCod    *BaseCod;
  22.  
  23. Prototype void InitCodeList(void);
  24. Prototype void DumpCode(FILE *fi, short srcHunk, long begOffset, long endOffset);
  25. Prototype RelocInfo *RelocAtOffset(long offset, short hunkNo);
  26. Prototype OpCod *DecodeOpCode(uword opCode, short *pmode1, short *pmode2, short *psiz, short *prs, short *prd);
  27. Prototype int MatchEa(uword opCode, short ea, short reg, long modes);
  28. Prototype int MatchSiz(uword opCode, OpCod *oc);
  29. Prototype int ExtensionWords(OpCod *oc, short mode, short opsize, uword *oper, FILE *fi);
  30. Prototype int IndexFormatExtWords(uword ext);
  31. Prototype char *ModeToStr(long offset, short srcHunk, uword opCode, uword **pwp, short mode, int altMode, short siz, short reg, short special);
  32.  
  33. /*
  34.  *  Reduce search requirements by splitting opcodes into a set of 16
  35.  *  lists based on their msb 4 bits (which never have dynamic info in them)
  36.  */
  37.  
  38. void
  39. InitCodeList(void)
  40. {
  41.     OpCod *oc;
  42.  
  43.     for (oc = Codes; oc->OpName; ++oc) {
  44.     if (oc->Id < 0)
  45.         continue;
  46.     oc->SibNext = BaseCod;
  47.     BaseCod = oc;
  48.     }
  49. }
  50.  
  51. void
  52. DumpCode(FILE *fi, short srcHunk, long begOffset, long endOffset)
  53. {
  54.     RelocInfo *r;
  55.  
  56.     while (begOffset < endOffset) {
  57.     uword    opCode;
  58.     static uword   oper[32];
  59.     short    words1;
  60.     short    words2;
  61.     short    i;
  62.     short    col;
  63.     OpCod    *oc;
  64.     short    mode1;
  65.     short    mode2;
  66.     short    siz;
  67.     short    rs;
  68.     short    rd;
  69.  
  70.     col = cprintf(" %02x.%08lx ", srcHunk, begOffset + StartPc);
  71.  
  72.     if ((r = RelocAtOffset(begOffset, srcHunk)) != NULL) {
  73.         long data = LoadRelocData(fi, r);
  74.         col += cprintf(" %s\n", RelocToStr(r, data, 1, 0, -1));
  75.         begOffset += r->ri_RelocSize;
  76.         continue;
  77.     }
  78.     if (freadl(&opCode, 2, 1, fi) != 1)
  79.         cerror(EFATAL, "Unexpected EOF");
  80.     begOffset += 2;
  81.  
  82.     col += cprintf(" %04x", opCode);
  83.  
  84.     oc = DecodeOpCode(opCode, &mode1, &mode2, &siz, &rs, &rd);
  85.     if (oc) {
  86.         words1 = ExtensionWords(oc, mode1, siz, oper, fi);
  87.         words2 = ExtensionWords(oc, mode2, siz, oper + words1, fi);
  88.     } else {
  89.         words1 = 0;
  90.         words2 = 0;
  91.     }
  92.  
  93.     for (i = 0; i < words1 + words2; ++i) {
  94.         r = RelocAtOffset(begOffset + i * 2, srcHunk);
  95.         if (r) {
  96.         char *str;
  97.  
  98.         switch(r->ri_RelocSize) {
  99.         case 1:
  100.             str = RelocToStr(r, oper[i] >> 8, 1, 1, -1);
  101.             break;
  102.         case 2:
  103.             str = RelocToStr(r, oper[i], 1, 2, -1);
  104.             break;
  105.         case 4:
  106.             str = RelocToStr(r, (oper[i] << 16) | oper[i+1], 1, 4, -1);
  107.             ++i;
  108.             break;
  109.         default:
  110.             str = RelocToStr(r, 0, 1, 0, -1);
  111.             break;
  112.         }
  113.         col += cprintf(" %s", str);
  114.         } else {
  115.         if ((r = RelocAtOffset(begOffset + i * 2 + 1, -1)) != NULL) {
  116.             if (r->ri_RelocSize != 1)
  117.             cerror(EWARN, "Expected 8 bit reloc");
  118.             col += cprintf(" %s", RelocToStr(r, oper[i] & 0xFF, 1, 2, -1));
  119.         } else {
  120.             col += cprintf(" %04x", oper[i]);
  121.         }
  122.         }
  123.     }
  124.  
  125.     ++col;
  126.     putc(' ', stdout);
  127.     while (col < 40) {
  128.         ++col;
  129.         putc(' ', stdout);
  130.     }
  131.  
  132.     /*
  133.      *  decode effective addresses
  134.      */
  135.  
  136.     if (oc) {
  137.         col += cprintf("%s", oc->OpName);
  138.  
  139.         col += 3;
  140.  
  141.         switch(siz) {
  142.         case 0:
  143.         printf("   ");
  144.         break;
  145.         case 1:
  146.         printf(".B ");
  147.         break;
  148.         case 2:
  149.         printf(".W ");
  150.         break;
  151.         case 4:
  152.         printf(".L ");
  153.         break;
  154.         default:
  155.         printf(".? ");
  156.         break;
  157.         }
  158.         while (col < 48) {
  159.         putc(' ', stdout);
  160.         ++col;
  161.         }
  162.         {
  163.         uword *iptr = oper;    /*  ptr to beginning of extension */
  164.  
  165.         if (mode2 == AB_REGS)
  166.             ++iptr;
  167.         if (mode1)
  168.             printf("%s", ModeToStr((iptr - oper) * 2 + begOffset, srcHunk, opCode, &iptr, mode1, mode2, siz, rs, oc->Special));
  169.         if (mode1 && mode2)
  170.             printf(",");
  171.         if (mode2) {
  172.             if (mode2 == AB_REGS)
  173.             iptr = oper;
  174.             printf("%s", ModeToStr((iptr - oper) * 2 + begOffset + words1, srcHunk, opCode, &iptr, mode2, mode1, siz, rd, oc->Special));
  175.         }
  176.         }
  177.     }
  178.     puts("");
  179.     begOffset += (words1 + words2) * 2;
  180.     }
  181.     if (begOffset > endOffset)
  182.     fseek(fi, endOffset - begOffset, SEEK_CUR);
  183. }
  184.  
  185. RelocInfo *
  186. RelocAtOffset(long offset, short hunkNo)
  187. {
  188.     RelocInfo *r = FindRelocOffset(offset, hunkNo);
  189.  
  190.     if (r && r->ri_SrcOffset == offset)
  191.     return(r);
  192.     return(NULL);
  193. }
  194.  
  195. /*
  196.  *  returns # of extension words and fills up ea structures
  197.  *  accordingly.
  198.  */
  199.  
  200. OpCod *
  201. DecodeOpCode(uword opCode, short *pmode1, short *pmode2, short *psiz, short *prs, short *prd)
  202. {
  203.     OpCod *oc;
  204.  
  205.     *pmode1 = 0;
  206.     *pmode2 = 0;
  207.     *psiz = 0;
  208.  
  209.     /*
  210.      *    find op-code
  211.      */
  212.  
  213.     for (oc = BaseCod; oc; oc = oc->SibNext) {
  214.     short am;
  215.  
  216.     {
  217.         uword template;
  218.  
  219.         if ((opCode & oc->Template) != oc->Template)
  220.         continue;
  221.  
  222.         if ((oc->SModes & AF_BBRANCH) && (char)opCode == 0)
  223.         continue;
  224.         if ((oc->SModes & AF_WBRANCH) && (char)opCode)
  225.         continue;
  226.  
  227.         template = opCode;
  228.  
  229.         if (oc->SModes & (AF_BBRANCH|AF_WBRANCH))
  230.         template &= 0xFF00;
  231.  
  232.         switch(oc->Special) {
  233.         case 0:
  234.         case IMM07: /*  unused  */
  235.         break;
  236.         case IMM18:
  237.         template &= 0xF1FF;
  238.         break;
  239.         case IMM0F:
  240.         template &= 0xFFF0;
  241.         break;
  242.         case IMM256:
  243.         template &= 0xFF00;
  244.         break;
  245.         case IMMBR: /*  unused  */
  246.         case IMMB:
  247.         break;
  248.         default:
  249.         cerror(ESOFT, "Unknown special code %s/%d", oc->OpName, oc->Special);
  250.         }
  251.  
  252.         if (oc->B_EAs >= 0)
  253.         template &= ~(7 << oc->B_EAs);
  254.         if (oc->B_Rs >= 0)
  255.         template &= ~(7 << oc->B_Rs);
  256.         if (oc->B_EAd >= 0)
  257.         template &= ~(7 << oc->B_EAd);
  258.         if (oc->B_Rd >= 0)
  259.         template &= ~(7 << oc->B_Rd);
  260.         if (oc->B_Siz >= 0)
  261.         template &= ~(3 << oc->B_Siz);
  262.  
  263.         if (template != oc->Template) {
  264.         if (DDebug)
  265.             printf("Template mismatch %04x %04x (%d %d %d %d %d)\n",
  266.             template, oc->Template, oc->B_EAs, oc->B_Rs, oc->B_EAd, oc->B_Rd, oc->B_Siz
  267.             );
  268.         continue;
  269.         }
  270.     }
  271.     if (DDebug)
  272.         printf("template match %s\n", oc->OpName);
  273.  
  274.     am = MatchEa(opCode, oc->B_EAs, oc->B_Rs, oc->SModes);
  275.     if (DDebug)
  276.         printf("r = %d\n", am);
  277.     if (am < 0)
  278.         continue;
  279.     if (oc->B_Rs >= 0)
  280.         *prs = (opCode >> oc->B_Rs) & 7;
  281.     *pmode1 = am;
  282.  
  283.     am = MatchEa(opCode, oc->B_EAd, oc->B_Rd, oc->DModes);
  284.     if (DDebug)
  285.         printf("r = %d\n", am);
  286.     if (am < 0)
  287.         continue;
  288.     if (oc->B_Rd >= 0)
  289.         *prd = (opCode >> oc->B_Rd) & 7;
  290.     *pmode2 = am;
  291.  
  292.     am = MatchSiz(opCode, oc);
  293.     if (am < 0)
  294.         continue;
  295.     *psiz = am;
  296.     break;
  297.     }
  298.     return(oc);
  299. }
  300.  
  301. int
  302. MatchEa(uword opCode, short ea, short reg, long modes)
  303. {
  304.     short i = 0;
  305.  
  306.     if (DDebug)
  307.     printf("matchea %04x %d %d %08lx\n", opCode, ea, reg, modes);
  308.     if (ea >= 0) {
  309.     if (reg >= 0) {
  310.         reg = (opCode >> reg) & 7;
  311.     } else {
  312.         reg = 0;
  313.     }
  314.     ea = (opCode >> ea) & 7;
  315.     switch(ea) {
  316.     case 0:
  317.         i = AB_DN;
  318.         break;
  319.     case 1:
  320.         i = AB_AN;
  321.         break;
  322.     case 2:
  323.         i = AB_INDAN;
  324.         break;
  325.     case 3:
  326.         i = AB_INDPP;
  327.         break;
  328.     case 4:
  329.         i = AB_MMIND;
  330.         break;
  331.     case 5:
  332.         i = AB_OFFAN;
  333.         break;
  334.     case 6:
  335.         i = AB_OFFIDX;
  336.         break;
  337.     case 7:
  338.         switch(reg) {
  339.         case 0:
  340.         i = AB_ABSW;
  341.         break;
  342.         case 1:
  343.         i = AB_ABSL;
  344.         break;
  345.         case 2:
  346.         i = AB_OFFPC;
  347.         break;
  348.         case 3:
  349.         i = AB_OFFIDXPC;
  350.         break;
  351.         case 4:
  352.         i = AB_IMM;
  353.         break;
  354.         default:
  355.         return(-1);
  356.         }
  357.     }
  358.     if ((modes & (1 << i)) == 0)
  359.         i = -1;
  360.     } else if (modes) {
  361.     for (i = 0; i < 32; ++i) {
  362.         if (modes - (1 << i) == 0)
  363.         break;
  364.     }
  365.     }
  366.     return(i);
  367. }
  368.  
  369. int
  370. MatchSiz(uword opCode, OpCod *oc)
  371. {
  372.     short siz = oc->B_Siz;
  373.     short sizes = oc->Sizes;
  374.  
  375.     if (siz >= 0) {
  376.     switch((opCode >> siz) & 3) {
  377.     case 0:
  378.         sizes &= S_B;
  379.         break;
  380.     case 1:
  381.         sizes &= S_W;
  382.         break;
  383.     case 2:
  384.         sizes &= S_L;
  385.         break;
  386.     case 3:
  387.         return(-1);
  388.     }
  389.     }
  390.     switch(sizes) {
  391.     case S_B:
  392.     return(1);
  393.     case S_W:
  394.     return(2);
  395.     case S_L:
  396.     return(4);
  397.     }
  398.     if (sizes == 0)
  399.     return(0);
  400.     cerror(EFATAL, "Software error, opcode/siz %04x %d %04x\n", opCode, siz, sizes);
  401.     return(-1);
  402. }
  403.  
  404. int
  405. ExtensionWords(OpCod *oc, short mode, short opsize, uword *oper, FILE *fi)
  406. {
  407.     short i = ExtWords[mode];
  408.  
  409.     if (i == -1) {    /*  imm/branch */
  410.     if (oc->Special == IMMB)
  411.         i = 1;
  412.     else if (oc->Special || (oc->SModes & AF_BBRANCH))
  413.         i = 0;
  414.     else
  415.         i = (opsize + 1) >> 1;  /* 1 for bw, 2 for long */
  416.     if (i)
  417.         freadl(oper, 2, i, fi);
  418.     } else if (i == -2) {
  419.     freadl(oper, 2, 1, fi);
  420.     i = IndexFormatExtWords(*oper);
  421.     if (i > 1)
  422.         freadl(oper + 1, 2, i - 1, fi);
  423.     } else if (i) {
  424.     freadl(oper, 2, i, fi);
  425.     }
  426.     return(i);
  427. }
  428.  
  429. int
  430. IndexFormatExtWords(uword ext)
  431. {
  432.     int n = 1;
  433.  
  434.     if (ext & 0x0100) {
  435.     switch(ext & 0x0030) {        /*    base displacement   */
  436.     case 0x0000:
  437.     case 0x0010:
  438.         break;
  439.     case 0x0020:
  440.         ++n;
  441.         break;
  442.     case 0x0030:
  443.         ++n;
  444.         ++n;
  445.         break;
  446.     }
  447.     switch(ext & 0x0003) {        /*    outder displacement */
  448.     case 0x0000:
  449.     case 0x0001:
  450.         break;
  451.     case 0x0002:
  452.         ++n;
  453.         break;
  454.     case 0x0003:
  455.         ++n;
  456.         ++n;
  457.         break;
  458.     }
  459.     }
  460.     return(n);
  461. }
  462.  
  463. /*
  464.  *  offset is the offset of the first extension word for this ea.
  465.  */
  466.  
  467. char *
  468. ModeToStr(long offset, short srcHunk, uword opCode, uword **pwp, short mode, int altMode, short siz, short reg, short special)
  469. {
  470.     uword *wptr = *pwp;
  471.     RelocInfo *r = NULL;
  472.     static char Buf[SMAX_BUF+128];
  473.  
  474.  
  475.     switch(mode) {
  476.     case AB_DN:
  477.     sprintf(Buf, "D%d", reg);
  478.     break;
  479.     case AB_AN:
  480.     sprintf(Buf, "A%d", reg);
  481.     break;
  482.     case AB_INDAN:
  483.     sprintf(Buf, "(A%d)", reg);
  484.     break;
  485.     case AB_INDPP:
  486.     sprintf(Buf, "(A%d)+", reg);
  487.     break;
  488.     case AB_MMIND:
  489.     sprintf(Buf, "-(A%d)", reg);
  490.     break;
  491.     case AB_OFFAN:
  492.     r = RelocAtOffset(offset, srcHunk);
  493.     sprintf(Buf, "%s(A%d)", RelocToStr(r, (short)wptr[0], 0, 2, -1), reg);
  494.     ++wptr;
  495.     break;
  496.     case AB_OFFIDX:
  497.     case AB_OFFIDXPC:
  498.     {
  499.         char regbuf[4];    /*  base register   */
  500.         char idxbuf[8];    /*  idx  register   */
  501.         uword ext = *wptr;
  502.  
  503.         if (mode == AB_OFFIDX) {
  504.         regbuf[0] = 'A';
  505.         regbuf[1] = reg + '0';
  506.         } else {
  507.         regbuf[0] = 'p';
  508.         regbuf[1] = 'c';
  509.         }
  510.         regbuf[2] = 0;
  511.  
  512.         {
  513.         idxbuf[0] = (ext & 0x8000) ? 'A' : 'D';
  514.         idxbuf[1] = ((ext >> 12) & 7) + '0';
  515.         idxbuf[2] = '.';
  516.         idxbuf[3] = (ext & 0x0800) ? 'L' : 'W';
  517.         idxbuf[4] = 0;
  518.  
  519.         switch(ext & 0x0600) {
  520.         case 0x0200:
  521.             strcpy(idxbuf + 4, "*2");
  522.             break;
  523.         case 0x0400:
  524.             strcpy(idxbuf + 4, "*4");
  525.             break;
  526.         case 0x0600:
  527.             strcpy(idxbuf + 4, "*8");
  528.             break;
  529.         }
  530.         }
  531.         if (ext & 0x0100) {       /*  MC68020 full format */
  532.         char *ptr = Buf;
  533.         short hda = 0;
  534.  
  535.         ++wptr;
  536.         offset += 2;          /*  skip first extension word */
  537.  
  538.         *ptr++ = '(';
  539.         if (ext & 0x0007)
  540.             *ptr++ = '[';
  541.  
  542.         switch(ext & 0x0030) {
  543.         case 0x0000:
  544.             ptr += csprintf(ptr, "<BADBD>");
  545.             hda = 1;
  546.             break;
  547.         case 0x0010:    /*  null    */
  548.             break;
  549.         case 0x0020:    /*  word    */
  550.             r = RelocAtOffset(offset, srcHunk);
  551.             ptr += csprintf(ptr, "%s", RelocToStr(r, (short)*wptr, 0, 2, (mode == AB_OFFIDXPC) ? srcHunk : -1));
  552.             ++wptr;
  553.             offset += 2;
  554.             hda = 1;
  555.             break;
  556.         case 0x0030:    /*  long    */
  557.             r = RelocAtOffset(offset, srcHunk);
  558.             ptr += csprintf(ptr, "%s", RelocToStr(r, *(long *)wptr, 0, 4, (mode == AB_OFFIDXPC) ? srcHunk : -1));
  559.             ++wptr;
  560.             ++wptr;
  561.             offset += 4;
  562.             hda = 1;
  563.             break;
  564.         }
  565.         if (hda) {
  566.             *ptr++ = ',';
  567.             hda = 0;
  568.         }
  569.         if ((ext & 0x0080) == 0) {
  570.             ptr += csprintf(ptr, "%s", regbuf);
  571.             hda = 1;
  572.         }
  573.         /*
  574.          *  if indirect post-indexed close bracket
  575.          */
  576.         if ((ext & 0x0044) == 0x0004) {
  577.             *ptr++ = ']';
  578.             hda = 1;
  579.         }
  580.         if (hda) {
  581.             *ptr++ = ',';
  582.             hda = 0;
  583.         }
  584.  
  585.         /*
  586.          *  index reg
  587.          */
  588.  
  589.         if ((ext & 0x0040) == 0) {
  590.             ptr += csprintf(ptr, "%s", idxbuf);
  591.             hda = 1;
  592.         }
  593.  
  594.         if ((ext & 0x0044) != 0x0004) {     /*    not ind post indexed */
  595.             if (ext & 0x0007) {
  596.             *ptr++ = ']';
  597.             hda = 1;
  598.             }
  599.         }
  600.  
  601.         /*
  602.          *  outer displacement
  603.          */
  604.  
  605.         switch(ext & 0x0003) {
  606.         case 0x0000:
  607.         case 0x0001:    /*  null    */
  608.             break;
  609.         case 0x0002:    /*  word    */
  610.             r = RelocAtOffset(offset, srcHunk);
  611.             ptr += csprintf(ptr, "%s", RelocToStr(r, (short)*wptr, 0, 2, -1));
  612.             ++wptr;
  613.             hda = 1;
  614.             break;
  615.         case 0x0003:    /*  long    */
  616.             r = RelocAtOffset(offset, srcHunk);
  617.             ptr += csprintf(ptr, "%s", RelocToStr(r, *(long *)wptr, 0, 4, -1));
  618.             ++wptr;
  619.             ++wptr;
  620.             hda = 1;
  621.             break;
  622.         }
  623.         *ptr++ = ')';
  624.         *ptr = 0;
  625.         } else {            /*  MC68000/020 brief    */
  626.         r = RelocAtOffset(offset, srcHunk);
  627.         if (r == NULL)
  628.             r = RelocAtOffset(offset + 1, srcHunk);
  629.         sprintf(Buf, "%s(%s,%s)", RelocToStr(r, (char)ext, 0, 1, (mode == AB_OFFIDXPC) ? srcHunk : -1), regbuf, idxbuf);
  630.         ++wptr;
  631.         }
  632.     }
  633.     break;
  634.     case AB_ABSW:
  635.     r = RelocAtOffset(offset, srcHunk);
  636.     sprintf(Buf, "%s.W", RelocToStr(r, wptr[0], 0, 2, srcHunk));
  637.     ++wptr;
  638.     break;
  639.     case AB_ABSL:
  640.     r = RelocAtOffset(offset, srcHunk);
  641.     if (r == NULL)
  642.         r = RelocAtOffset(offset + 2, srcHunk);
  643.     sprintf(Buf, "%s", RelocToStr(r, (wptr[0] << 16) | wptr[1], 0, 4, srcHunk));
  644.     wptr += 2;
  645.     break;
  646.     case AB_OFFPC:
  647.     {
  648.         long addoff;
  649.  
  650.         /*
  651.          *    Attempt to do the relocation.  If we can get our hands on
  652.          *    a symbol we are in good shape.
  653.          */
  654.  
  655.         r = RelocAtOffset(offset, srcHunk);
  656.         addoff = FixRelocOffset(r, offset);
  657.  
  658.         sprintf(Buf, "%s(pc)", RelocToStr(r, (short)wptr[0] + addoff, 0, 0, srcHunk));
  659.     }
  660.     ++wptr;
  661.     break;
  662.     case AB_IMM:
  663.     switch(special) {
  664.     case IMM18:
  665.         {
  666.         short cnt = (opCode >> 9) & 7;
  667.  
  668.         if (cnt == 0)
  669.             cnt = 8;
  670.         sprintf(Buf, "#%d", cnt);
  671.         }
  672.         break;
  673.     case IMM0F:
  674.         sprintf(Buf, "#%d", opCode & 15);   /*  warning, decimal    */
  675.         break;
  676.     case IMM256:
  677.         r = RelocAtOffset(offset - 1, srcHunk);
  678.         if (r == NULL)
  679.         r = RelocAtOffset(offset - 2, srcHunk);
  680.         sprintf(Buf, "#%s", RelocToStr(r, (char)opCode, 0, 1, -1));
  681.         break;
  682.     case IMMB:  /*    next byte   */
  683.         r = RelocAtOffset(offset, srcHunk);
  684.         if (r == NULL)
  685.         r = RelocAtOffset(offset + 1, srcHunk);
  686.         sprintf(Buf, "#%s", RelocToStr(r, (char)wptr[0], 0, 1, -1));
  687.         ++wptr;
  688.         break;
  689.     default:
  690.         r = RelocAtOffset(offset, srcHunk);
  691.         switch(siz) {
  692.         case 0:
  693.         sprintf(Buf, "#?");
  694.         break;
  695.         case 1:
  696.         if (r == NULL)
  697.             r = RelocAtOffset(offset + 1, srcHunk);
  698.         sprintf(Buf, "#%s", RelocToStr(r, (short)wptr[0], 0, 1, -1));
  699.         ++wptr;
  700.         break;
  701.         case 2:
  702.         sprintf(Buf, "#%s", RelocToStr(r, (short)wptr[0], 0, 2, -1));
  703.         ++wptr;
  704.         break;
  705.         case 4:
  706.         sprintf(Buf, "#%s", RelocToStr(r, (wptr[0] << 16) | wptr[1], 0, 4, -1));
  707.         wptr += 2;
  708.         break;
  709.         default:
  710.         sprintf(Buf, "#?");
  711.         break;
  712.         }
  713.         break;
  714.     }
  715.     break;
  716.     case AB_REGS:
  717.     {
  718.         short i;
  719.         short j = 0;
  720.         short beg = -1;
  721.  
  722.         for (i = 0; i < 16; ++i) {
  723.         short regNo;
  724.  
  725.         if (altMode == AB_MMIND)
  726.             regNo = wptr[0] & (1 << (15 - i));
  727.         else
  728.             regNo = wptr[0] & (1 << i);
  729.  
  730.         if (regNo) {
  731.             if (beg == -2)
  732.             j += csprintf(Buf + j, "/");
  733.             if (beg < 0) {
  734.             if (i < 8)
  735.                 j += csprintf(Buf + j, "D%d", i);
  736.             else
  737.                 j += csprintf(Buf + j, "A%d", i - 8);
  738.             beg = i;
  739.             }
  740.         }
  741.         if (regNo == 0 || i == 8) {
  742.             if (beg >= 0) {
  743.             --i;
  744.             if (beg < i) {
  745.                 if (i < 8)
  746.                 j += csprintf(Buf + j, "-D%d", i);
  747.                 else
  748.                 j += csprintf(Buf + j, "-A%d", i - 8);
  749.             }
  750.             ++i;
  751.             beg = -2;
  752.             }
  753.         }
  754.         }
  755.     }
  756.     ++wptr;
  757.     break;
  758.     case AB_BBRANCH:
  759.     case AB_WBRANCH:
  760.     {
  761.         long addoff;
  762.  
  763.         if (opCode & 0xFF) {
  764.         r = RelocAtOffset(offset - 1, srcHunk);
  765.         addoff = FixRelocOffset(r, offset);
  766.  
  767.         if (r == NULL) {
  768.             r = RelocAtOffset(offset - 2, srcHunk);
  769.             addoff = FixRelocOffset(r, offset);
  770.         }
  771.         sprintf(Buf, "%s", RelocToStr(r, (char)opCode + addoff, 0, 4, srcHunk));
  772.         } else {
  773.         r = RelocAtOffset(offset, srcHunk);
  774.         addoff = FixRelocOffset(r, offset);
  775.  
  776.         sprintf(Buf, "%s", RelocToStr(r, (short)wptr[0] + addoff, 0, 4, srcHunk));
  777.         /* XXX ? */
  778.         ++wptr;
  779.         }
  780.     }
  781.     break;
  782.     case AB_CCR:
  783.     sprintf(Buf, "CCR");
  784.     break;
  785.     case AB_SR:
  786.     sprintf(Buf, "SR");
  787.     break;
  788.     case AB_USP:
  789.     sprintf(Buf, "USP");
  790.     break;
  791.     default:
  792.     return("?");
  793.     }
  794.     *pwp = wptr;
  795.     return(Buf);
  796. }
  797.  
  798.